package cc.abanlee.module.system.service.auth.impl;

import cc.abanlee.framework.common.enums.UserTypeEnum;
import cc.abanlee.framework.common.exception.ServiceException;
import cc.abanlee.framework.common.util.jwt.JwtUtil;
import cc.abanlee.module.system.controller.admin.auth.vo.AuthLoginReqVO;
import cc.abanlee.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import cc.abanlee.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import cc.abanlee.module.system.dal.dataobject.user.AdminUserDO;
import cc.abanlee.module.system.enums.ErrorCodeConstants;
import cc.abanlee.module.system.enums.oauth2.OAuth2ClientConstants;
import cc.abanlee.module.system.service.auth.AdminAuthService;
import cc.abanlee.module.system.service.oauth2.OAuth2TokenService;
import cc.abanlee.module.system.service.user.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;
import java.util.UUID;

/**
 *
 */
@Service
public class AdminAuthServiceImpl implements AdminAuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private AdminUserService userService;

    @Resource
    private OAuth2TokenService oauth2TokenService;

    @Override
    public AdminUserDO authenticate(String username, String password) {

        AdminUserDO user = userService.getUserByUsername(username);
        if (user == null) {
            throw new ServiceException(ErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS);
        }


        if (!userService.isPasswordMatch(password, user.getPassword())) {
            throw new ServiceException(ErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS);
        }

        return user;
    }

//    @Override
//    public AuthLoginRespVO login(@Valid AuthLoginReqVO reqVO) {
//
//        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(reqVO.getUserName(),reqVO.getPassword());
//        try{
//            Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//            SecurityContextHolder.getContext().setAuthentication(authenticate);
//        }catch (BadCredentialsException e) {
//            throw new ServiceException(ErrorCodeConstants.AUTH_FAIL);
//        }catch (Exception e){
//            throw new ServiceException(ErrorCodeConstants.LOGIN_FAIL);
//        }
//
//        String jwt = JwtUtil.createJWT(reqVO.getUserName());
//        redisTemplate.opsForValue().set("token-"+reqVO.getUserName(), jwt);
//        AuthLoginRespVO authLoginRespVO=new AuthLoginRespVO();
//        authLoginRespVO.setToken(jwt);
//        return authLoginRespVO;
//    }

    @Override
    public AuthLoginRespVO login(@Valid AuthLoginReqVO reqVO) {


        AdminUserDO user = this.authenticate(reqVO.getUsername(), reqVO.getPassword());


        // 创建 Token 令牌，记录登录日志
        return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername());
    }


    @Override
    public AuthLoginRespVO refreshToken(String refreshToken) {
        String jwt = JwtUtil.createJWT("zhangsan");
        redisTemplate.opsForValue().set("token-zhangsan", jwt);
        AuthLoginRespVO authLoginRespVO=new AuthLoginRespVO();
        //authLoginRespVO.setToken(jwt);
        return null;
    }


    private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId,String username){

        // 创建访问令牌
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
                OAuth2ClientConstants.CLIENT_ID_DEFAULT, null);
        // 构建返回结果
        return convert(accessTokenDO);

    }


    private UserTypeEnum getUserType() {
        return UserTypeEnum.ADMIN;
    }

    public AuthLoginRespVO convert(OAuth2AccessTokenDO bean) {
        if ( bean == null ) {
            return null;
        }

        AuthLoginRespVO authLoginRespVO = new AuthLoginRespVO();

        authLoginRespVO.setUserId( bean.getUserId() );
        authLoginRespVO.setAccessToken( bean.getAccessToken() );
        authLoginRespVO.setRefreshToken( bean.getRefreshToken() );
        authLoginRespVO.setExpiresTime( bean.getExpiresTime() );

        return authLoginRespVO;
    }
}
